package miblab.school.maps;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MapController;
import com.google.android.maps.Overlay;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.BitmapFactory;

import java.util.ArrayList;
import java.util.List;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import miblab.school.R;
import miblab.school.ScreenSchoolActivity;
import miblab.school.SystemParameters;
import miblab.school.maps.GeoClusterer.GeoCluster;

public class Cluster extends MapActivity{
	private static final String TAG = Cluster.class.getSimpleName();
	private String file;
	private boolean file_diff;
	private static double[] lat = new double[SystemParameters.number], lon= new double[SystemParameters.number];
	private File[] list;
	private double[][][] Cumm_Points; 

	/* google map variables */
	/** MapView object */
	private MapView mapView_;
	/** MapController object */
	private MapController mapCtrl_;

	private List<GeoItem> geoItems_ = new ArrayList<GeoItem>();

	// marker icons
	private List<MarkerBitmap> markerIconBmps_ = new ArrayList<MarkerBitmap>();


	//private GeoItem geoItems[];
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.mapc);




		// set up  map view and location
		mapView_ = (MapView)findViewById(R.id.map);
		mapCtrl_ = mapView_.getController();
		mapCtrl_.setZoom(13);
		mapView_.setBuiltInZoomControls(true);
		mapView_.displayZoomControls(true);
		mapView_.setStreetView(true);
		//		mapCtrl_.setCenter(new GeoPoint(lat,lng));

		mapView_.invalidate();
		// prepare for marker icons.
		// small icon for maximum 10 items
		markerIconBmps_.add(
				new MarkerBitmap(
						BitmapFactory.decodeResource(getResources(), R.drawable.red1),
						BitmapFactory.decodeResource(getResources(), R.drawable.red2),
						new Point(20,20),
						14,
						10)
				);
		// large icon. 100 will be ignored.
		markerIconBmps_.add(
				new MarkerBitmap(
						BitmapFactory.decodeResource(getResources(), R.drawable.red2),
						BitmapFactory.decodeResource(getResources(), R.drawable.red3),
						new Point(28,28),
						16,
						100)
				);
		Bundle extras = getIntent().getExtras();
		if(extras !=null) {
			file_diff = extras.getBoolean("EXTRA_DIFF");
		}
		if(file_diff)
		{
			Cumm_Points = getfiles();
			int[][] coord = locations(Cumm_Points);
			for(int j=0; j<SystemParameters.number;j++)
			{
				
				double l = Cumm_Points[coord[j][0]][coord[j][1]][0];
				double ln = Cumm_Points[coord[j][0]][coord[j][1]][1];
				SDwrite(SystemParameters.LocName[j]+"1.txt",l,ln);
				Log.i(TAG,"Lon: "+l/1E6+" LAT: "+ln/1E6);

			}

		}
		else
		{
			file=Getfilename();
			plotpoints(file);
		}
	}
	//**********************On Pause ******************************************************		
	@Override
	protected void onPause() {
		super.onPause();
		finish();
	}

	@Override
	public void onBackPressed() {
		//Log.d("CDA", "onBackPressed Called");
		Intent intent = new Intent(Cluster.this,ScreenSchoolActivity.class);
		startActivity(intent);
	}
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	/**
	 * onCreateOptionsMenu handler
	 */
	public void Plot()
	{
		// create clusterer instance
		float screenDensity = Cluster.this.getResources().getDisplayMetrics().density;
		GeoClusterer clusterer = new GeoClusterer(mapView_,markerIconBmps_,screenDensity);
		// add geoitems for clustering
		for(int i=0; i<geoItems_.size(); i++) {
			clusterer.addItem(geoItems_.get(i));
		}

		//clusterer.redraw();

		List<GeoCluster> clusters = clusterer.getClustersInViewport();
		Log.i(TAG,"Size "+clusters.size() + SystemParameters.number);



		for(int i = mapView_.getZoomLevel(); i>1;i--)
		{

			boolean status = false;
			mapCtrl_.setZoom(i);
			clusterer.resetViewport();   		
			clusters = clusterer.getClustersInViewport();
			Log.i(TAG,"Size " + i + ": "+clusters.size() +" : "+ SystemParameters.number);

			if(clusters.size()==SystemParameters.number)
			{
				// now redraw the cluster. it will create markers.
				clusterer.redraw();
				mapView_.invalidate();




				for(int j = 0; j < clusters.size();j++)
				{

					GeoPoint centre = clusters.get(j).getLocation();
					Log.i(TAG,"Lon: "+centre.getLongitudeE6()+" LAT: "+centre.getLatitudeE6());
					lat[j]=centre.getLongitudeE6()/1E6;
					lon[j]=centre.getLatitudeE6()/1E6;
					SDwrite(SystemParameters.LocName[j]+"1.txt",lat[j],lon[j]);
				}
				if(status)
					Toast.makeText(Cluster.this, "Location Set", Toast.LENGTH_LONG).show();

				break;
			}

		}




		// now you can see items clustered on the map.
		// zoom in/out to see how icons change.
	} 
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		MenuItem menu_Revert = menu.add(0,1,0,"Cluster");
		menu_Revert.setIcon(android.R.drawable.ic_menu_myplaces);
		return true;
	}

	/**
	 * onOptionsItemSelected handler
	 * since clustering need MapView to be created and visible,
	 * this sample do clustering here.
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case 1: {

			mapView_.getOverlays().clear();
			mapView_.invalidate();

			//done=true;
			Plot();
			break;
		}
		}
		return true;
	}

	//**********************SD Write ******************************************************		
	public boolean SDwrite(String sFileName, double lat, double lon)
	{
		boolean state = false;
		try
		{
			File root = new File(SystemParameters.path, "School");
			if (!root.exists()) {
				root.mkdirs();
			}
			File gpxfile = new File(root,sFileName);
			FileWriter writer = new FileWriter(gpxfile);
			writer.write("Lat:"+lat+":Lon:"+lon+":Tim:"+0.0);
			writer.flush();
			writer.close();
			state = true;
		}
		catch(IOException e)
		{
			Toast.makeText(this, "Insert SD Card", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
			state = false;
		}

		return state;

	}
	//**********************Get filename************************************************
	public String Getfilename()
	{		

		String FN = null;

		//To Write to an SD

		Bundle extras = getIntent().getExtras();
		if(extras !=null) {
			FN = extras.getString("EXTRA_FILENAME");
		}

		return FN; 
	}


	public void plotpoints(String filename)
	{

		List<GeoPoint> geoPoints = new ArrayList<GeoPoint>();
		//-----------------------PARSE STRING--------------------------------------------------------------	

		String aDataRow = "";
		String strlat = "";
		String strlon ="";
		int i=0;
		double[] timespent= new double[4];
		double[] loc= new double[3];
		for(int j=0;j<4;j++)
			timespent[j]=0;
		//-------------------------------------------------------------------------------------				  	

		try
		{
			{	 
				File gpxfile = new File(filename);
				FileInputStream fIn = new FileInputStream(gpxfile);
				if(!gpxfile.exists())
				{
					Log.i(TAG, "File Error");
				}
				BufferedReader myReader = new BufferedReader(
						new InputStreamReader(fIn));

				int count=0; 
				while ((aDataRow = myReader.readLine()) != null) 
				{
					
					//-------------------------------------------------------------------------------------	
					String[] tokens = aDataRow.split(":");

					for(String t : tokens)
					{	

						i++;
						if(i==2)
						{	
							strlat=t;
							try {
								loc[0]=Double.parseDouble(strlat);
							} catch (NumberFormatException e) {
								Log.i(TAG, "Wrong Number 1");
								e.printStackTrace();
							}
						}

						if(i==4)
						{
							strlon=t;
							try {
								loc[1]=Double.parseDouble(strlon);
							} catch (NumberFormatException e) {
								Log.i(TAG, "Wrong Number 2");
								e.printStackTrace();
							}
						}
					}
					i=0;

					if ((strlat!= null)&&(strlon!=null)) {
						i=0;
						GeoItem point = new GeoItem(count,(int) (loc[0] * 1E6),(int) (loc[1] * 1E6));
						count++;
						geoItems_.add(point);
						if(!file_diff)
						{
							GeoPoint point1 = new GeoPoint(
									(int) (loc[0] * 1E6), 
									(int) (loc[1] * 1E6));
							Log.d(TAG,""+loc[0]+""+loc[1]);
							geoPoints.add(point1);

							mapCtrl_.animateTo(point1);
							mapCtrl_.setZoom(16);

							// add marker 
							MapOverlay mapOverlay = new MapOverlay();
							mapOverlay.setPointToDraw(point1);
							List<Overlay> listOfOverlays = mapView_.getOverlays();
							listOfOverlays.add(mapOverlay);
							mapView_.invalidate();
						}
					}
					//-----------------------------------------------------------------------------------		

				}
				myReader.close();

			}

		} 
		//-------------------------------------------------------------------------------------		
		catch(NullPointerException e)
		{
			e.printStackTrace();
		} 
		catch(Exception e)
		{
			Toast.makeText(this, "Insert SD Card", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		} 
		//-----------------------END OF PARSE STRING--------------------------------------------------------------	

	}


	public double[][][] getfiles()
	{
		File mfile = null;
		mfile = new File(SystemParameters.path+"/School");
		double Points[][][] = new double[mfile.listFiles().length][SystemParameters.number][2]; 


		list=mfile.listFiles();
		try {
			for(int i = 0;i<5;i++ )
			{


				String FN=""+list[i];
				Log.d(TAG,FN);
				if((FN.contains("Hospital.txt"))||(FN.contains("Home.txt"))||(FN.contains("School.txt"))||(FN.contains("Password.txt"))||(FN.contains("Username.txt")))
				{
				}
				else if((FN.contains("Hospital1.txt"))||(FN.contains("Home1.txt"))||(FN.contains("School1.txt"))||(FN.contains("Password.txt"))||(FN.contains("Username.txt")))
				{
				}

				else
				{
					Log.d(TAG,FN);
					plotpoints(FN);
					Plot();
					for(int j=0;j<SystemParameters.number;j++)
					{
						Points[i][j][0]=lat[j];
						Points[i][j][1]=lon[j];
					}
				}	
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return Points;
	}
	public int[][] locations(double[][][] Points)
	{
		int[][] Coordinates = new int[SystemParameters.number][2];

		int[] count = new int[SystemParameters.number];
		int temp =0;
		for(int i=0;i<SystemParameters.number;i++)
		{
			count[i]=0;
		}

		double[] lt = new double[SystemParameters.number],ln=new double[SystemParameters.number];
		for (int i=0;i<Points.length; i++)
		{
			for(int j=0; j<SystemParameters.number; j++)
			{
				lt[j]=Points[i][j][0];
				ln[j]=Points[i][j][1];
				for(int k=0;k<Points.length; k++)
				{
					if((lt[j]==Points[k][j][0])&&(ln[j]==Points[k][j][1]))
						temp++;
				}
				for(int l =0; l<SystemParameters.number;l++)
				{
					if(temp>count[l])
					{
						count[l]=temp;
						Coordinates[l][0]=i;
						Coordinates[l][1]=j;
						break;
					}
				}
			}

		}
		return Coordinates ;

	}
	class MapOverlay extends Overlay
	{
		private GeoPoint pointToDraw;

		public void setPointToDraw(GeoPoint point) {
			pointToDraw = point;
		}

		public GeoPoint getPointToDraw() {
			return pointToDraw;
		}

		@Override
		public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
			super.draw(canvas, mapView, shadow);                   

			// convert point to pixels
			Point screenPts = new Point();
			mapView.getProjection().toPixels(pointToDraw, screenPts);


			// add marker
			Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.red);
			canvas.drawBitmap(bmp, screenPts.x, screenPts.y - 24, null); // 24 is the height of image        
			return true;
		}
	} 


}
